#include <bits/stdc++.h>
using namespace std;
struct user{
    string name, type, password;
} users[101];
int usercnt = 0;
bool user_exist(string name){
    for (int i=0; i<usercnt; i++){
        if (users[i].name == name){
            return true;
        }
    }
    return false;
}
struct var{
    string name, value;
} vars[101];
int vars_i = 0;
string reguser(string type, string name, string password, string confirm_password){
    if (usercnt >= 100){
        cout<<"用户过多。"<<endl;
        return "UserMax";
    }
    if (name == ""){
        cout<<"错误：用户名为空。"<<endl;
        return "NameNullErr";
    }
    if (user_exist(name)){
        cout<<"用户已经存在。"<<endl;
        return "UserExistedErr";
    }
    users[usercnt].name = name;
    users[usercnt].type = type;
    if (password != confirm_password){
        cout<<"错误：密码确认失败。"<<endl;
        return "ConfirmErr";
    }
    users[usercnt].password = password;
    cout<<"注册成功！"<<endl;
    usercnt++;
    return "NormalExit";
}
bool logined = true;
int loging_i = 0;
string login()
{
    cout<<"准备开始登录。"<<endl;
    cout<<"用户名：";
    string name;
    getline(cin, name);
    bool founduser = false;
    int login_i;
    for (int i=0;i<usercnt; i++){
        if (users[i].name == name){
            cout<<"用户存在。"<<endl;
            login_i = i;
            founduser = true;
            break;
        }
    }
    if(!founduser){
        cout<<"不存在此用户。"<<endl;
        return "UserNotFound";
    }
    string password;
    cout<<"接下来，请您输入密码：";
    getline(cin, password);
    if (password != users[login_i].password){
        cout<<"密码错误。"<<endl;
        return "WrongPassword";
    }
    cout<<"登录成功。"<<endl;
    logined = true;
    loging_i = login_i;
    system("pause");
    return "NormalExit";
}
void prnHelp(){
    cout<<"(root) destroy --- 销毁系统。"<<endl;
    cout<<"help --- 获取帮助。"<<endl;
    cout<<"clear --- 清空屏幕。"<<endl;
    cout<<"add [FileName]--- 添加文件(FileName: 文件名)。"<<endl;
    cout<<"(Tips): 查看文件内容可以直接输入文件名。"<<endl;
    cout<<"edit [FileName] --- 编辑文件(FileName: 文件名)。"<<endl;
    cout<<"del [FileName] --- 删除文件(FileName: 文件名)。"<<endl;
    cout<<"(root) reg [Name] [Password] [Confirm] --- 创建账户(Name: 账户名称, Password: 账户密码, Confirm: 确认密码)。"<<endl;
    cout<<"logout --- 退出登录。"<<endl;
    cout<<"filelist --- 文件列表。"<<endl;
    cout<<"userlist --- 用户列表。"<<endl;
    cout<<"myinfo --- 我的信息。"<<endl;
    cout<<"define [VariableName] [VariableValue] --- 定义变量。"<<endl;
    cout<<"reset [VariableName] [NewValue] --- 更改变量值。"<<endl;
    cout<<"delete [VariableName] --- 删除变量。"<<endl;
    cout<<"do [ScriptName] --- 执行hcxvmos脚本文件。"<<endl;
}
struct file{
    string name, content = "";
} files[101];
int files_i = 0;
string lower(string s){
    int s_len = s.size();
    for(int i=0;i<s_len;i++){
        if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;
    }
    return s;
}
bool choice(){
    string choice;
    cout<<"确定？(y/n): ";
    getline(cin, choice);
    choice = lower(choice);
    if(choice == "y" || choice == "yes") return true;
    return false;
}
string tokens[101];
int tokens_i = 0;
void clear_tokens(){
    for (int i=0; i<101; i++){
        tokens[i] = "";
    }
}
string tokenizer(string cmd)
{
    //清空tokens数组
    clear_tokens();
    tokens_i = 0;
    cmd += " ";
    int cmd_len = cmd.size();
    int insign = 0;
    string spliting = "";
    for (int i=0; i<cmd_len; i++){
        if (tokens_i >= 100){
            return "CmdLong";
        }
        if (cmd[i] == ' ' && insign == 0){
            tokens[tokens_i] = spliting;
            tokens_i++;
            spliting = "";
            continue;
        }
        if (cmd[i] == '"'){
            if (insign % 2){
                //还没有凑整
                //这个是结尾的引号
                insign--;
                //不用录入
                continue;
            }
            //已经凑整
            //这个是开头的引号
            insign++;
            //录入，不用管他，执行到下面自动录入
        }
        //录入
        spliting += string(1, cmd[i]);
        if (i == cmd_len-1 && insign > 0){
            //引号不匹配
            return "SignNotEnd";
        }
    }
    return "NormalExit";
}
//true表示wyy
bool wyy_string(string s){
    if (s == "") return true;
    int s_len = s.size();
    for (int i=0; i<s_len; i++){
        if (s[i] != ' '){
            return false;
        }
    }
    return true;
}
void del_wyy_tokens(){
    string local_tokens[101];
    int local_i = 0;
    for (int i=0; i<tokens_i; i++){
        if (!wyy_string(tokens[i])){
            local_tokens[local_i] = tokens[i];
            local_i++;
        }
    }
    swap(tokens, local_tokens);
    tokens_i = local_i;
}
string delHead(string s){
    if (s[0] != '"') return s;
    int s_len = s.size();
    string result = "";
    for (int i=1; i<s_len; i++){
        result += string(1, s[i]);
    }
    return result;
}
void prnEditHelp(){
    cout<<"add [String] --- 添加字符串到末尾。"<<endl;
    cout<<"del [Number] --- 删除末尾Number位字符。"<<endl;
    cout<<"endl --- 添加换行符。"<<endl;
    cout<<"exit --- 退出编辑模式。"<<endl;
}
bool all_is_num(string s){
    int s_len = s.size();
    for (int i=0; i<s_len; i++){
        if (s[i] < '0' || s[i] > '9'){
            return false;
        }
    }
    return true;
}
int string_to_int(string s){
    int series = 1;
    int s_len = s.size(), result = 0;
    for (int i=s_len-1; i>=0; i--){
        result += series * (s[i] - '0');
    }
    return result;
}
bool check_name(string name){
    name = delHead(name);
    if (name == "") return false;
    int name_len = name.size();
    for (int i=0; i<name_len; i++){
        if (name[i] == '"') return false;
    }
    for (int i=0; i<files_i; i++){
        if (files[i].name == name){
            return false;
        }
    }
    return true;
}
void delFile_i(int delpos){
    file local_files[101];
    int local_files_i = 0;
    for (int i=0; i<files_i; i++){
        if (i != delpos){
            local_files[local_files_i].name = files[i].name;
            local_files[local_files_i].content = files[i].content;
            local_files_i++;
        }
    }
    files_i--;
    swap(files, local_files);
}
string delFile(string name){
    for (int i=0; i<files_i; i++){
        if (files[i].name == name){
            delFile_i(i);
            return "NormalExit";
        }
    }
    //文件没有被删除
    return "FileNotFound";
}
void del_var_i(int del_i){
    var local_vars[101];
    int local_vars_i = 0;
    for (int i=0; i<vars_i; i++){
        if (i == del_i){
            continue;
        }
        local_vars[local_vars_i].name = vars[i].name;
        local_vars[local_vars_i].value = vars[i].value;
        local_vars_i++;
    }
    vars_i--;
    swap(local_vars, vars);
}
string splited_cmds[101];
int splited_cmds_i = 0;
string split_command(int fi){
    int now_i = 0, filesize = files[fi].content.size();
    string now_spliting = "";
    while (true){
        if (now_i >= filesize){
            splited_cmds[splited_cmds_i] = now_spliting;
            splited_cmds_i++;
            return "NormalExit";
        }
        if (splited_cmds_i >= 100){
            return "Long";
        }
        if (files[fi].content[now_i] == '\n'){
            splited_cmds[splited_cmds_i] = now_spliting;
            now_spliting = "";
            splited_cmds_i++;
            now_i++;
            continue;
        }
        now_spliting += files[fi].content[now_i];
        now_i++;
    }
}
void edit_file(int editing_i){
    while (true){
        system("cls");
        cout<<files[editing_i].name<<":"<<endl;
        cout<<files[editing_i].content<<endl;
        cout<<"命令："<<endl;
        prnEditHelp();
        cout<<"EditMode > ";
        string editcmd;
        getline(cin, editcmd);
        string splitcode = tokenizer(editcmd);
        del_wyy_tokens();
        if (splitcode == "SignNotEnd"){
            cout<<"引号不匹配。"<<endl;
            system("pause");
            continue;
        }
        if (tokens[0] == "add"){
            if (tokens[1] == ""){
                cout<<"缺少必要的参数。"<<endl;
                system("pause");
                continue;
            }
            if (tokens[1][0] == '"'){
                tokens[1] = delHead(tokens[1]);
                files[editing_i].content += tokens[1];
            }
            else{
                bool found = false;
                for (int i=0; i<vars_i; i++){
                    if (vars[i].name == tokens[1]){
                        found = true;
                        files[editing_i].content += vars[i].value;
                        break;
                    }
                }
                if (!found){
                    cout << "未定义变量。" << endl;
                    system("pause");
                    continue;
                }
            }
        }
        else if (tokens[0] == "del"){
            if (!all_is_num(tokens[1])){
                cout<<"参数无效。"<<endl;
                system("pause");
                continue;
            }
            int n = string_to_int(tokens[1]);
            //删除结尾n位
            int content_size = files[editing_i].content.size();
            if (n > content_size){
                cout<<"错误：参数过大。"<<endl;
                system("pause");
                continue;
            }
            string result = "";
            for (int i=0; i<content_size-n-1; i++){
                result += string(1, files[editing_i].content[i]);
            }
            files[editing_i].content = result;
        }
        else if (tokens[0] == "endl"){
            files[editing_i].content += "\n";
        }
        else if (tokens[0] == "exit"){
            break;
        }
        else{
            if (tokens[0] == ""){
                system("cls");
                continue;
            }
            cout<<"未定义编辑命令。"<<endl;
            system("pause");
        }
        system("cls");
    }
    cout<<"即将退出编辑模式。"<<endl;
    system("pause");
    system("cls");
}
void do_command(string cmd){
    string splitcode = tokenizer(cmd);
    del_wyy_tokens();
        
    if (splitcode == "SignNotEnd"){
        cout<<"错误：引号不匹配。"<<endl;
        return;
    }
    if (splitcode == "CmdLong"){
        cout << "命令太长。" << endl;
        return;
    }
    if (tokens[0] == "help"){
        prnHelp();
    }
    else if(tokens[0] == "destroy"){
        if (users[loging_i].type != "root"){
            cout<<"该账户的权限需要提升。"<<endl;
            return;
        }
        bool confirm = true;
        for(int i=0;i<3;i++){
            bool result = choice();
            if (!result){
                confirm = false;
                break;
            }
        }
        if (!confirm) return;
        //毁灭吧
        exit(0);
    }
    else if (tokens[0] == "clear"){
        system("cls");
    }
    else if (tokens[0] == "add"){
        //参数: tokens[1]: 文件名
        if (files_i >= 100){
            cout<<"文件数量已达上限。请通过删除文件以节省空间。"<<endl;
        }
        if (tokens[1] == ""){
            cout<<"缺少必要的参数(FileName Not Found)。"<<endl;
            return;
        }
        if (!check_name(tokens[1])){
            cout<<"禁止文件名里包含不被允许的符号或者没有文件名，或者重名。"<<endl;
            return;
        }
        if (tokens[1][0] == '"'){
            //直接引用文件名
            tokens[1] = delHead(tokens[1]);  //去除引号标识符
            files[files_i].name = tokens[1];
            files_i++;
        }
        else{
            bool found = false;
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[1]){
                    found = true;
                    if (files_i >= 100){
                        cout<<"文件数量已达上限。请通过删除文件以节省空间。"<<endl;
                        return;
                    }
                    files[files_i].name = vars[i].value;
                    files_i++;
                    break;
                }
            }
            if (!found){
                cout << "未定义变量。" << endl;
            }
        }
    }
    else if (tokens[0] == "edit"){
        //寻找文件编号
        if (tokens[1] == ""){
            cout<<"缺少文件名。"<<endl;
            return;
        }
        if (tokens[1][0] == '"'){
            tokens[1] = delHead(tokens[1]);
        }
        else{
            bool found = false;
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[1]){
                    found = true;
                    tokens[1] = vars[i].value;
                    break;
                }
            }
            if (!found){
                cout << "未定义变量。" << endl;
                return;
            }
        }
        int editing_i = 0;
        bool found = false;
        for (int i=0; i<files_i; i++){
            if (files[i].name == tokens[1]){
                editing_i = i;
                found = true;
                break;
            }
        }
        if (!found){
            cout<<"没有找到文件。"<<endl;
            return;
        }
        //进入编辑模式
        edit_file(editing_i);
    }
    else if (tokens[0] == "del"){
        if (tokens[1] == ""){
            cout<<"缺少必要的参数：文件名。"<<endl;
            return;
        }
        if (tokens[1][0] == '"'){
            tokens[1] = delHead(tokens[1]);
            string delcode = delFile(tokens[1]);
            if (delcode == "FileNotFound"){
                cout<<"文件不存在。"<<endl;
            }
        }
        else{
            bool found = false;
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[1]){
                    string delcode = delFile(vars[i].value);
                    if (delcode == "FileNotFound"){
                        cout << "文件不存在。" << endl;
                    }
                    break;
                }
            }
            if (!found){
                cout << "未定义变量。" << endl;
            }
        }
    }
    else if (tokens[0] == "reg"){
        if (users[loging_i].type != "root"){
            cout<<"仅有root可以创建账户。"<<endl;
            return;
        }
        //tokens[1]名称, tokens[2]密码
        if (tokens[1] == "" || tokens[2] == "" || tokens[3] == ""){
            cout<<"缺少参数。"<<endl;
            return;
        }
        if (tokens[1][0] == '"'){
            tokens[1] = delHead(tokens[1]);
            if (tokens[2][0] == '"')
            {
                tokens[2] = delHead(tokens[2]);
                if (tokens[3][0] == '"'){
                    tokens[3] = delHead(tokens[3]);
                    reguser("user", tokens[1], tokens[2], tokens[3]);
                }
                else{
                    bool found = false;
                    for (int i=0; i<vars_i; i++){
                        if (vars[i].name == tokens[3]){
                            found = true;
                            reguser("user", tokens[1], tokens[2], vars[i].value);
                            break;
                        }
                    }
                    if (!found){
                        cout << "变量未找到。" << endl;
                    }
                }
            }
            else{
                cout<<"当前版本不支持引用变量当作密码。"<<endl;
                return;
            }
        }
        else{
            cout<<"该版本不支持引用变量当作账户名称。"<<endl;
            return;
        }
    }
    else if (tokens[0] == "logout"){
        system("cls");
        logined = false;
        return;
    }
    else if (tokens[0] == "filelist"){
        if (files_i == 0){
            cout << "无文件。" << endl;
            return;
        }
        for (int i=0; i<files_i; i++){
            cout << files[i].name << endl;
        }
    }
    else if (tokens[0] == "userlist"){
        cout << "Name / Type";
        if (users[loging_i].type == "root"){
            cout << " / Password" << endl;
        }
        else{
            cout << endl;
        }
        for (int i=0; i<usercnt; i++){
            cout << users[i].name << "  ---  " << users[i].type;
            if (users[loging_i].type == "root"){
                cout << "  ---  " << users[i].password << endl;
            }
            else{
                cout << endl;
            }
        }
    }
    else if (tokens[0] == "myinfo"){
        cout << "我的用户名：" << users[loging_i].name << endl;
        cout << "我的权限：" << users[loging_i].type << endl;
        cout << "我的密码：" << users[loging_i].password << endl;
    }
    else if (tokens[0] == "define"){
        if (tokens[1][0] != '"'){
            cout << "当前版本不支持引用变量当作参数。" << endl;
            return;
        }
        bool found = false;
        if (tokens[2][0] != '"'){
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[2]){
                    found = true;
                    if (vars_i >= 100){
                        cout << "变量空间不足。请删除一些变量以节省空间。" << endl;
                    }
                    vars[vars_i].name = delHead(tokens[1]);
                    vars[vars_i].value = vars[i].value;
                    vars_i++;
                }
            }
        }
        if (!found && tokens[2][0] != '"'){
            cout << "变量未定义。" << endl;
            return;
        }
        tokens[1] = delHead(tokens[1]);
        tokens[2] = delHead(tokens[2]);
        if (vars_i >= 100){
            cout << "变量空间不足。请删除一些变量以节省空间。" << endl;
        }
        vars[vars_i].name = tokens[1];
        vars[vars_i].value = tokens[2];
        vars_i++;
    }
    else if (tokens[0] == "reset"){
        if (tokens[1][0] != '"'){
            cout << "当前版本不支持引用变量当作参数。" << endl;
            return;
        }
        bool found = false;
        if (tokens[2][0] != '"'){
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[2]){
                    found = true;
                    bool reseted = false;
                    for (int j=0; j<vars_i; j++){
                        if (vars[j].name == delHead(tokens[1])){
                            reseted = true;
                            vars[j].value = vars[i].value;
                            break;
                        }
                    }
                    if (!reseted){
                        cout << "变量未找到。" << endl;
                        return;
                    }
                    break;
                }
            }
        }
        if (!found && tokens[2][0] != '"'){
            cout << "未定义变量。" << endl;
            return;
        }
        tokens[1] = delHead(tokens[1]);
        tokens[2] = delHead(tokens[2]);
        bool reseted = false;
        for (int i=0; i<vars_i; i++){
            if (vars[i].name == tokens[1]){
                reseted = true;
                vars[i].value = tokens[2];
                break;
            }
        }
        if (!reseted){
            cout << "变量未找到。" << endl;
        }
    }
    else if (tokens[0] == "delete"){
        bool found = false;
        if (tokens[1][0] != '"'){
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[1]){
                    found = true;
                    bool found_var = false;
                    for (int i=0; i<vars_i; i++){
                        if (vars[i].name == tokens[1]){
                            found_var = true;
                            del_var_i(i);
                            break;
                        }
                    }
                    if (!found_var){
                        cout << "变量未找到。" << endl;
                        return;
                    }
                    break;
                }
            }
        }
        if (!found && tokens[1][0] != '"'){
            cout << "未定义变量。" << endl;
            return;
        }
        tokens[1] = delHead(tokens[1]);
        bool found_var = false;
        for (int i=0; i<vars_i; i++){
            if (vars[i].name == tokens[1]){
                found_var = true;
                del_var_i(i);
                break;
            }
        }
        if (!found_var){
            cout << "变量未找到。" << endl;
        }
    }
    else if (tokens[0] == "do"){
        bool found = false, need_delhead = true;
        if (tokens[1][0] != '"'){
            for (int i=0; i<vars_i; i++){
                if (vars[i].name == tokens[1]){
                    found = true;
                    need_delhead = false;
                    tokens[1] = vars[i].value;
                    break;
                }
            }
        }
        if (!found && tokens[1][0] != '"'){
            cout << "未定义变量。" << endl;
            return;
        }
        if (need_delhead){
            tokens[1] = delHead(tokens[1]);
        }
        int fi;
        found = false;
        for (int i=0; i<files_i; i++){
            if (files[i].name == tokens[1]){
                fi = i;
                found = true;
                break;
            }
        }
        if (!found){
            cout << "未找到脚本文件。" << endl;
            return;
        }
        string split_lines_code = split_command(fi);
        if (split_lines_code == "Long"){
            cout << "太长的脚本文件。" << endl;
            return;
        }
        // 分解成功，逐行执行
        for (int i=0; i<splited_cmds_i; i++){
            do_command(splited_cmds[i]);
        }
        cout << "脚本执行完毕。" << endl;
    }
    else{
        if (tokens[0] == ""){
            return;
        }
        //变量优先查找，文件最后查找
        bool isvar = false;
        for (int i=0; i<vars_i; i++){
            if (vars[i].name == tokens[0]){
                cout << vars[i].value << endl;
                isvar = true;
                break;
            }
        }
        if (isvar){
            return;
        }
        bool isFile = false;
        for (int i=0; i<files_i; i++){
            if (files[i].name == tokens[0]){
                cout<<files[i].content<<endl;
                isFile = true;
                break;
            }
        }
        if (isFile){
            return;
        }
        cout<<"命令无效。"<<endl;
    }
}
int main()
{
    cout<<"欢迎初次使用hcx系统。该系统仅支持中文模式。"<<endl;
    system("pause");
    cout<<"接下来将为您注册root用户。"<<endl;
    while (true)
    {
        string name;
        cout<<"账户名称：";
        getline(cin, name);
        string password;
        cout<<"密码：";
        getline(cin, password);
        cout<<"确认密码：";
        string confirm;
        getline(cin, confirm);
        string regcode = reguser("root", name, password, confirm);
        if (regcode != "NormalExit"){
            cout<<"请重新注册。"<<endl;
            continue;
        }
        break;
    }
    cout<<"root用户注册成功，您接下来可以以root的权限使用这个系统。"<<endl;
    system("pause");
    system("cls");

    while (true)
    {
        if(!logined){
            cout<<"您已经退出登录。请登录。"<<endl;
            // 显示所有用户
            cout << "此电脑上的所有用户：" << endl;
            cout << "Name / Type" << endl;
            for (int i=0; i<usercnt; i++){
                cout << users[i].name << "  ---  " << users[i].type << endl;
            }
            while (true){
                string logcode = login();
                if(logcode != "NormalExit"){
                    cout<<"请重新登录。"<<endl;
                    continue;
                }
                break;
            }
            system("cls");
            continue;
        }

        string cmd;
        cout<<users[loging_i].type<<" > ";
        getline(cin, cmd);
        do_command(cmd);
    }
    return 0;
}